<template>
  <el-drawer v-model="drawerVisible" :title="drawerTitle" direction="rtl" size="80%" class="result"
    v-if="drawerVisible">
    <el-card shadow="never" class="result-info">
      <span>
        {{ info.creator }}
        <el-divider direction="vertical" />
        结果状态： <el-tag :type="info.resultStatus == '成功' ? 'success' : (info.resultStatus == '失败' ? 'danger' : 'info')">{{
          info.resultStatus }}</el-tag>
        <el-divider direction="vertical" />
        执行状态： <el-tag :type="info.exeStatus == '已完成' ? 'primary' : 'info'">{{ info.exeStatus }}</el-tag>
      </span>
      <span>执行时间：{{ formatMsToLocalTime(info.createTime) }} 至 {{ formatMsToLocalTime(info.endTime) }}</span>
    </el-card>
    <el-skeleton :loading="false" animated>
      <el-row :gutter="10" justify="space-between">
        <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
          <el-card shadow="never" class="result-item">
            <template #header>
              <div class="card-header">
                <span>报告分析</span>
              </div>
            </template>
            <p class="item">
              <span>
                <el-icon class="icon">
                  <AlarmClock />
                </el-icon>
                运行总耗时
              </span>
              <span class="num">{{ info.costTime }}<small>(ms)</small></span>
            </p>
            <p class="item">
              <span>
                <el-icon class="icon">
                  <AlarmClock />
                </el-icon>
                请求总耗时
              </span>
              <span class="num">{{ info.requestDuration }}<small>(ms)</small></span>
            </p>
            <p class="item">
              <span>
                <el-icon class="icon radio">
                  <Check />
                </el-icon>
                断言成功率
              </span>
              <span class="num">{{ info.assertPassRate * 100 }}<small>(%)</small></span>
            </p>
          </el-card>
        </el-col>
        <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
          <el-card shadow="never" class="result-item">
            <template #header>
              <div class="card-header">
                <span>接口分析</span>
              </div>
            </template>
            <el-skeleton :loading="false" animated>
              <el-row :gutter="10">
                <el-col :xl="16" :lg="16" :md="16" :sm="16" :xs="16">
                  <Echart :options="pieInterfaceData" ref="echartsRef" :height="170" />
                </el-col>
                <el-col :xl="4" :lg="4" :md="4" :sm="4" :xs="4" class="col-flex"><span>{{ info.successCount || 0
                    }}</span><span>{{ info.failCount || 0 }}</span><span>{{ info.pendingCount || 0 }}</span></el-col>
                <el-col :xl="4" :lg="4" :md="4" :sm="4" :xs="4" class="col-flex">
                  <span>{{ successCountRatio }}%</span><span>{{ failCountRatio }}%</span><span>{{
                    pendingCountRatio
                  }}%</span></el-col>
              </el-row>
            </el-skeleton>
          </el-card>
        </el-col>
        <el-col :xl="8" :lg="8" :md="8" :sm="8" :xs="8">
          <el-card shadow="never" class="result-item">
            <template #header>
              <div class="card-header">
                <span>请求分析</span>
              </div>
            </template>
            <el-skeleton :loading="false" animated>
              <el-row :gutter="10">
                <el-col :xl="20" :lg="20" :md="20" :sm="20" :xs="20">
                  <Echart :options="pieQueryData" ref="echartsRef1" :height="170" />
                </el-col>
                <el-col :xl="4" :lg="4" :md="4" :sm="4" :xs="4" class="col-flex"><span>{{ requestPassRate
                    }}%</span><span>{{ requestFailRate }}%</span><span>{{ requestPendingRate
                    }}%</span></el-col>
              </el-row>
            </el-skeleton>
          </el-card>
        </el-col>
      </el-row>
      <el-card shadow="never" class="result-report">
        <template #header>
          <div class="card-header">
            <span>报告明细</span>
          </div>
        </template>
        <el-collapse @change="changeCollapse" v-if="info.steps?.length">
          <el-collapse-item :name="index" v-for="(item, index) of info.steps" :key="index">
            <template #title>
              <span class="result-report_left">
                <span class="method" :style="{ color: methodStyle[item.requestType] }">{{ item.requestType }}</span>
                <span class="name">{{ item.name }}</span>
              </span>
              <span class="result-report_right">
                <span><small
                    :style="{ background: changeColor(item) + '22', color: changeColor(item), padding: '2px 5px' }">{{
                      item.responseResult }}</small></span>
                <span>状态码：<small :style="{ color: changeColor(item) }">{{ item.responseCode
                    }}</small></span>
                <span>响应时间：<small :style="{ color: changeColor(item) }">{{ item.responseTime
                    }}ms</small></span>
                <span>响应大小：<small :style="{ color: changeColor(item) }">{{ item.responseSize
                    }}B</small></span>
              </span>
            </template>
            <ResponseCom :data="item.response" />
          </el-collapse-item>
        </el-collapse>
        <el-empty :image-size="50" description="暂无数据" v-else />
      </el-card>
    </el-skeleton>
  </el-drawer>
</template>

<script setup lang="ts">
import * as SceneApi from '@/api/scene'
import { useAppStore } from '@/store/modules/app'
import { AlarmClock, Check } from '@element-plus/icons-vue'
import { pieOptions } from '../components/echartsData'
import { set } from 'lodash-es'
import ResponseCom from '../../components/ResponseCom.vue'
import { formatMsToLocalTime } from '@/utils/formatTime'
const echartsRef = ref()
const echartsRef1 = ref()
const pieInterfaceData = reactive(pieOptions()) as any
const pieQueryData = reactive(pieOptions()) as any
const appStore = useAppStore()
const projectId = computed(() => appStore.getSelectProject)
const drawerVisible = ref(false)
const drawerTitle = ref('')
const info = ref({} as any)
const successCountRatio = computed(() => {
  const val = (info.value.successCount / info.value.apiCount * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const failCountRatio = computed(() => {
  const val = (info.value.failCount / info.value.apiCount * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const pendingCountRatio = computed(() => {
  const val = (info.value.pendingCount / info.value.apiCount * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const requestPassRate = computed(() => {
  const val = (info.value.requestPassRate * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const requestFailRate = computed(() => {
  const val = (info.value.requestFailRate * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const requestPendingRate = computed(() => {
  const val = (info.value.requestPendingRate * 100).toFixed(2)
  return isNaN(Number(val)) ? 0 : val
})
const changeColor = (data) => {
  const code = data.responseCode
  const result = data.responseResult
  if (code >= 200 && code < 300) {
    return '#00c261'
  } else if (code >= 300 && code < 400) {
    return '#536ae3'
  } else if (code >= 400 && code < 500) {
    return '#e6e22a'
  } else if (code >= 500) {
    return '#ea1c24'
  }
  if (!code && result) {
    return result == '成功' ? '#00c261' : '#ea1c24'
  }
}
/** 请求类型颜色定义 */
const methodStyle = ref({
  'GET': '#17b26a',
  'POST': '#ef6820',
  'DELETE': '#f04438',
  'PUT': '#2e90fa',
})
/** 打开弹窗 */
const open = async (row?: any) => {
  drawerVisible.value = true
  drawerTitle.value = row.name
  resetForm()
  await getInfo(row.id)
  getPieInterfaceData()
  getPieQueryData()
  // 重置图表尺寸
  nextTick(() => {
    echartsRef.value.triggerResize()
    echartsRef1.value.triggerResize()
  })
}

const changeCollapse = async (list) => {
  list.forEach(async (l) => {
    const currentStep = info.value.steps[l]
    if (!currentStep.response) {
      const data = await SceneApi.getSceneReportStep({ id: currentStep.id })
      let { responseHeaders, responseContent, requestBody, requestHeaderList, requestParamsList, responseResult, responseCode, responseTime, responseSize, requestUrl, cookies, responseContentType, extractorResponse,
        assertInfos,imageUrl } = data
      currentStep.response = {
        requestHeaderList,
        requestBody,
        requestParamsList,
        responseHeaders,
        responseContent,
        extractorResponse,
        assertInfos,
        imageUrl,
        responseResult: { responseCode, responseTime, responseSize, responseResult, requestUrl, cookies, responseContentType }
      }
    }
  })
}
/** 主题切换时更新图表颜色 */
const init = () => {
  const textColor = appStore.getIsDark ? '#fff' : 'rgb(48, 49, 51)'
  pieInterfaceData.title.textStyle.color = textColor
  pieInterfaceData.legend.textStyle.color = textColor
  pieQueryData.title.textStyle.color = textColor
  pieQueryData.legend.textStyle.color = textColor
}
/** 监听主题切换 */
watchEffect(() => {
  init()
})
/** 重置表单 */
const resetForm = () => {

}
defineExpose({ open }) // 提供 open 方法，用于打开弹窗
/** 接口数图表 */
const getPieInterfaceData = async () => {
  const data = [
    { name: '成功', value: info.value.successCount || 0 },
    { name: '失败', value: info.value.failCount || 0 },
    { name: '未执行', value: info.value.pendingCount || 0 }
  ]
  set(
    pieInterfaceData,
    'legend.data',
    ['成功', '失败', '未执行']
  )
  set(
    pieInterfaceData,
    'title.text',
    '接口数'
  )
  set(
    pieInterfaceData,
    'series[0].data',
    data
  )
  set(
    pieInterfaceData,
    'title.subtext',
    info.value.apiCount || '--'
  )
}
/** 请求分析图表 */
const getPieQueryData = async () => {
  const data = [
    { name: '通过', value: info.value.requestPassRate || 0 },
    { name: '失败', value: info.value.requestFailRate || 0 },
    { name: '未执行', value: info.value.requestPendingRate || 0 }
  ]
  set(
    pieQueryData,
    'legend.data',
    ['通过', '失败', '未执行']
  )
  set(
    pieQueryData,
    'title.text',
    '请求通过率'
  )
  set(
    pieQueryData,
    'series[0].data',
    data
  )
  set(
    pieQueryData,
    'title.top',
    '50%'
  )
}
/** 获取场景报告信息 */
const getInfo = async (id) => {
  let res = await SceneApi.getSceneReport({ id })
  info.value = res
}
</script>

<style lang="scss">
.result {
  .el-drawer__header {
    margin-bottom: 20px;
  }

  .el-drawer__body {
    padding: 0 10px;
  }

  .el-card {
    margin: 5px 0;
  }

  .el-card__header {
    padding: 10px;
    font-size: 14px;
  }

  .el-card__body {
    font-size: 14px;
    position: relative;
  }

  .result-info {
    height: 40px !important;

    .el-card__body {
      display: flex;
      justify-content: space-between;
    }
  }

  .result-item {

    .el-card__body {
      height: 170px;
    }

    p.item {
      border: 1px solid var(--el-border-color-light);
      display: flex;
      justify-content: space-between;
      line-height: 38px;
      padding-right: 10px;
      border-radius: 5px;
      margin: 15px 0;
      .icon {
        background: #409eff;
        color: #fff;
        height: 40px;
        display: inline-block;
        line-height: 40px;
        width: 40px;
        text-align: center;
        border-radius: 5px;
        margin-right: 5px;
        font-size: 18px;
      }

      .radio {
        background: #30e254;
      }

      small {
        color: #959598;
        margin-left: 5px;
      }
    }
  }

  .result-report {
    margin-top: 15px;
    height: calc(100% - 320px) !important;

    .el-collapse {
      overflow: auto;
    }

    .el-collapse-item__header {
      position: relative;
    }

    .el-collapse-item {
      // height: 100%;

      .el-collapse-item__wrap {
        height: 300px;
      }

      .el-collapse-item__content {
        height: 100%;

        .content {
          overflow: auto;
          height: 100%;
        }
      }
    }

    &_left {
      .tag {
        color: #409eff;
        border: 1px solid #409eff;
        padding: 2px 5px;
        border-radius: 0 10px 10px 0;
        margin-right: 10px;
      }
    }

    &_right {
      position: absolute;
      right: 30px;
      color: #959598;
      display: flex;
      align-items: center;

      span {
        margin: 0 10px;
        display: inline-block;

        small {
          font-size: 14px;
        }

        &:first-child {
          border-radius: 3px;
          line-height: 20px;
          overflow: hidden;
        }
      }

    }
  }

  .col-flex {
    display: flex;
    align-items: center;
    justify-content: space-around;
    flex-direction: column;
  }

  .el-empty {
    position: absolute;
    top: 50%;
    left: 50%;
    margin-top: -50px;
    margin-left: -28px;
    height: auto !important;
  }

  .method {
    font-style: normal;
    margin-right: 5px;
    font-size: 12px;
    font-weight: 900;
  }
}
</style>
